package com.open.capacity.finance.task;

import com.open.capacity.finance.constant.AuditWarnStatus;
import com.open.capacity.finance.dao.AuditModelDao;
import com.open.capacity.finance.dao.AuditModelWarnScopeDao;
import com.open.capacity.finance.dto.AuditModelBaseResult;
import com.open.capacity.finance.entity.AuditModel;
import com.open.capacity.finance.entity.AuditModelWarn;
import com.open.capacity.finance.entity.AuditModelWarnLog;
import com.open.capacity.finance.service.AbstractAuditMakeResultFactory;
import com.open.capacity.finance.service.AuditModelWarnLogService;
import com.open.capacity.finance.service.AuditModelWarnService;
import com.open.capacity.user.dao.SysCompanyDao;
import com.open.capacity.user.model.SysCompany;
import com.open.capacity.user.service.SysCompanyService;
import com.open.capacity.user.service.SysUserRelationService;
import com.open.capacity.user.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;


/**
 * @desc 指标搞告警任务
 */
@Component
@Slf4j
public class AuditModelWarnTask implements ScheduledOfTask {

    public AbstractAuditMakeResultFactory service;

    @Autowired
    private AuditModelDao modelDao;

    @Autowired
    private AuditModelWarnScopeDao warnScopeDao;

    @Autowired
    private SysUserService userService;

    @Autowired
    private AuditModelWarnService warnService;

    @Autowired
    private AuditModelWarnLogService warnLogService;

    @Autowired
    private SysCompanyDao companyDao;

    @Autowired
    private SysUserRelationService relationService;

    @Autowired
    private TaskExecutor taskExecutor;

    public String MODELID = "1";

    Integer cronId = null;

    @Override
    public void setCronId(Integer cronId) {
        this.cronId = cronId;
    }

    @Override
    public void execute() {
        try {
            log.info("start excute " + this.getClass().getSimpleName() + "_" + MODELID);
            int excuteResult = 1;
            String resultUrl = null;
            AuditModel model = modelDao.findById(MODELID);
            if (model.getWarnNeed() != null && (model.getStatus().equals(0) || model.getWarnNeed().equals(0))) {
                log.info("指标[" + model.getName() + "]无需预警");
                return;
            }

            try {
                Map<String, Object> param = new HashMap<>();

                List<SysCompany> companyList = companyDao.findList(new HashMap<>());
                for (SysCompany company : companyList) {
                    param.put("companyId", company.getId());
                    param.put("kjnd", model.getDefaultKjnd());
                    AuditModelBaseResult data = service.getData(MODELID, param);
                    if (data.getExists().equals(1)) {
                        resultUrl = data.getResultFileUrl();
                        AuditModelWarn lastWarn = warnService.findLastByModelId(MODELID, company.getId(), null);
                        //忽略结果集相同的告警
                        if (lastWarn == null || !data.getResultFileMd5().equals(lastWarn.getResultMd5())) {
                            AuditModelWarn warn = new AuditModelWarn();
                            warn.setModelId(MODELID);
                            warn.setModelName(model.getCode() + " " + model.getName());
                            warn.setWarnLevel(data.getExists());
                            warn.setResultMd5(data.getResultFileMd5());
                            warn.setResultUrl(data.getResultFileUrl());
                            warn.setDealFlag(0);
                            warn.setCreateTime(new Date());
                            warn.setCompanyId(company.getId());
                            warn.setStatus(AuditWarnStatus.NEW.getCode());
                            warnService.save(warn);
                        }
                    }

                    //异步将离线文件写入数据库
                    int finalExcuteResult = excuteResult;
                    String finalResultUrl = resultUrl;
                    CompletableFuture.runAsync(() -> {
                        AuditModelWarnLog log = new AuditModelWarnLog();
                        log.setModelId(MODELID);
                        log.setCompanyId(company.getId());
                        log.setModelName(model.getCode() + " " + model.getName());
                        log.setResultUrl(finalResultUrl);
                        log.setExcuteResult(finalExcuteResult);
                        log.setCreateTime(new Date());
                        warnLogService.save(log);
                    }, taskExecutor);
                }
            } catch (Exception e) {
                excuteResult = -1;
            }

        } catch (Throwable e) {
            log.error("execute process has error(Throwable) : ", e);
        }
    }

    @Override
    public void trigger(String startTime) throws IOException {

    }
}
